﻿using Admin.ApplicationLib.Entities;
using Admin.ApplicationLib.EntityConfigurations;
using Admin.ApplicationLib.Services;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Swimj.ApplicationLib.Entities;
using Swimj.Core.Providers;
using Swimj.Core.Securities;

namespace Admin.ApplicationLib
{
    public class AdminApplicationDbContext : IdentityDbContext<UserEntity, RoleEntity, Guid>
    {
        private readonly ISecurityUser _securityUser;
        private readonly IDateTimeProvider _dateTimeProvider;

        public ISecurityUser SecurityUser => _securityUser;

        public IDateTimeProvider DateTimeProvider => _dateTimeProvider;

        public AdminApplicationDbContext(DbContextOptions dbContextOptions,
            ISecurityUser securityUser,
            IDateTimeProvider dateTimeProvider) : base(dbContextOptions)
        {
            _securityUser = securityUser;
            _dateTimeProvider = dateTimeProvider;
        }

        //public AdminApplicationDbContext(DbContextOptions<AdminApplicationDbContext> options) : base(options)
        //{
        //}

        public DbSet<PermissionEntity> Permissions { get; set; } = default!;

        public new DbSet<RoleClaimEntity> RoleClaims { get; set; } = default!;

        public new DbSet<UserRoleEntity> UserRoles { get; set; } = default!;

        // public DbSet<JobDetailEntity> JobDetails { get; set; } = default!;

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.ApplyConfiguration(new PermissionEntityTypeConfiguration());

            // builder.Entity<PermissionEntity>(b =>
            // {
            //     // b.HasOne(p => p.ParentPermission)
            //     //     .WithMany()
            //     //     .HasForeignKey(p => p.ParentId);
            //
            //     b.HasOne<PermissionEntity>().WithMany().HasForeignKey(p => p.ParentId);
            //
            //     b.ToTable("AspNetPermissions").HasKey(p => p.Id);
            // });

            // builder.Entity<JobDetailEntity>(b =>
            // {
            //     b.ToTable("QRTZ_JOB_DETAILS").HasKey(p => new { p.SchedName, p.JobName, p.JobGroup });
            //
            //     b.Property(p => p.SchedName).HasColumnName("SCHED_NAME");
            //     b.Property(p => p.JobName).HasColumnName("JOB_NAME");
            //     b.Property(p => p.JobGroup).HasColumnName("JOB_GROUP");
            //     b.Property(p => p.JobClassName).HasColumnName("JOB_CLASS_NAME");
            //     b.Property(p => p.IsDurable).HasColumnName("IS_DURABLE");
            //     b.Property(p => p.IsNonconcurrent).HasColumnName("IS_NONCONCURRENT");
            //     b.Property(p => p.IsUpdateData).HasColumnName("IS_UPDATE_DATA");
            //     b.Property(p => p.RequestsRecovery).HasColumnName("REQUESTS_RECOVERY");
            //     b.Property(p => p.JobData).HasColumnName("JOB_DATA");
            // });
        }

        public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = new CancellationToken())
        {
            foreach (var entry in ChangeTracker.Entries<IAuditableEntity>().ToList())
            {
                switch (entry.State)
                {
                    case EntityState.Added:
                        entry.Entity.CreatedOn = _dateTimeProvider.GetCurrentDateTime();
                        entry.Entity.CreatedBy = _securityUser.GetUserId()?.ToString();
                        break;

                    case EntityState.Modified:
                        entry.Entity.LastModifiedOn = _dateTimeProvider.GetCurrentDateTime();
                        entry.Entity.LastModifiedBy = _securityUser.GetUserId()?.ToString();
                        break;
                }
            }

            return await base.SaveChangesAsync(cancellationToken);
        }
    }
}